package cn.springspace.app.service;

import cn.springspace.app.config.ArtemisConfiguration;
import cn.springspace.app.enums.EventTypeEnum;
import cn.springspace.kotlinapp.model.Door;
import cn.springspace.kotlinapp.model.DoorEvent;
import cn.springspace.kotlinapp.repository.DoorEventRepository;
import cn.springspace.kotlinapp.repository.DoorRepository;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
@Slf4j
public class ArtemisService {

    private static final String ARTEMIS_PATH = "/artemis";

    @Autowired
    private ArtemisConfiguration artemisConfiguration;

    @Autowired
    private DoorRepository doorRepository;

    @Autowired
    private DoorEventRepository doorEventRepository;

    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");

    private static final ObjectMapper objectMapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    public void refreshDoorState() {
        String doorIndexCodes = artemisConfiguration.getDoorIndexCodes();
        Optional.of(getDoors(doorIndexCodes))
                .orElse(Collections.emptyList())
                .stream()
                .forEach(door -> doorRepository.save(door));

    }

    public void refreshDoorEvent() {
        Integer pageNo = 1;
        Integer pageSize = 100;
        List<DoorEvent> doorEventList = new ArrayList<>();
        queryDoorEvent(pageNo, pageSize, doorEventList);
        doorEventList.stream()
                .forEach(doorEvent -> doorEventRepository.save(doorEvent));
    }

    public void queryDoorEvent(Integer pageNo, Integer pageSize, List<DoorEvent> doorEventList) {
        log.info("query door event, pageNo: {}, pageSize: {}", pageNo, pageSize);
        ArtemisConfig config = new ArtemisConfig();
        config.setHost(artemisConfiguration.getArtemisUrl()); // 代理API网关nginx服务器ip端口
        config.setAppKey(artemisConfiguration.getArtemisAppKey());  // 秘钥appkey
        config.setAppSecret(artemisConfiguration.getArtemisSecret());// 秘钥appSecret
        final String getCamsApi = ARTEMIS_PATH + "/api/acs/v2/door/events";
        Map<String, Object> paramMap = new HashMap<>();// post请求Form表单参数
        paramMap.put("pageNo", pageNo);
        paramMap.put("pageSize", pageSize);
        String body = JSON.toJSONString(paramMap);
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCamsApi);
            }
        };
        try {
            log.info("config: {}, path:{}, body: {}", JSON.toJSONString(config), path, body);
            String result = ArtemisHttpUtil.doPostStringArtemis(config, path, body, null, null, "application/json");
            log.info("result: {}", result);
            JSONObject jsonObject = JSON.parseObject(result);
            if ("0".equals(jsonObject.getString("code"))) {
                JSONObject data = jsonObject.getJSONObject("data");
                if (data != null) {

                    JSONArray authDoorList = data.getJSONArray("list");
                    authDoorList.stream()
                            .map(doorEvent -> JSON.parseObject(doorEvent.toString()))
                            .filter(doorEvent -> doorEvent.getInteger("inAndOutType") != -1)
                            .map(doorEvent -> {
                                String eventTime = doorEvent.getString("eventTime");
                                if (StringUtils.isNotBlank(eventTime)) {
                                    ZonedDateTime zonedDateTime = ZonedDateTime.parse(eventTime);
                                    doorEvent.put("eventTime", zonedDateTime.format(formatter));
                                }
                                String receiveTime = doorEvent.getString("receiveTime");
                                if (StringUtils.isNotBlank(receiveTime)) {
                                    ZonedDateTime zonedDateTime = ZonedDateTime.parse(receiveTime);
                                    doorEvent.put("receiveTime", zonedDateTime.format(formatter));
                                }
                                String eventType = doorEvent.getString("eventType");
                                if (StringUtils.isNotBlank(eventType)) {
                                    doorEvent.put("eventType", EventTypeEnum.getLabelCnByValue(eventType));
                                }
                                return doorEvent;
                            })
                            .forEach(doorEvent -> {
                                try {
                                    doorEventList.add(objectMapper.readValue(doorEvent.toString(), DoorEvent.class));
                                } catch (IOException e) {
                                    throw new RuntimeException(e);
                                }
                            });
                    Integer tatalPage = data.getInteger("totalPage");
                    if (tatalPage > pageNo) {
                        queryDoorEvent(pageNo + 1, pageSize, doorEventList);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private List<Door> getDoors(String doorIndexCodes) {
        log.info("query door, doorIndexCodes: {}", doorIndexCodes);
        ArtemisConfig config = new ArtemisConfig();
        config.setHost(artemisConfiguration.getArtemisUrl()); // 代理API网关nginx服务器ip端口
        config.setAppKey(artemisConfiguration.getArtemisAppKey());  // 秘钥appkey
        config.setAppSecret(artemisConfiguration.getArtemisSecret());// 秘钥appSecret
        final String getCamsApi = ARTEMIS_PATH + "/api/acs/v1/door/states";
        Map<String, Object> paramMap = new HashMap<>();// post请求Form表单参数
        paramMap.put("doorIndexCodes", doorIndexCodes.split(","));
        String body = JSON.toJSONString(paramMap);
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCamsApi);
            }
        };
        List<Door> doorList = new ArrayList<>();
        try {
            log.info("config: {}, path:{}, body: {}", JSON.toJSONString(config), path, body);
            String result = ArtemisHttpUtil.doPostStringArtemis(config,path, body, null, null, "application/json");
            log.info("result: {}", result);
            JSONObject jsonObject = JSON.parseObject(result);
            if ("0".equals(jsonObject.getString("code"))) {
                JSONObject data = jsonObject.getJSONObject("data");
                if (data != null) {
                    JSONArray authDoorList = data.getJSONArray("authDoorList");
                    authDoorList.forEach(item -> {
                        JSONObject door = (JSONObject) item;
                        try {
                            doorList.add(objectMapper.readValue(door.toString(), Door.class));
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    });
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return doorList;
    }

    private String testDoorState() {
        return "{\"code\":\"0\",\"msg\":\"success\",\"data\":{\"authDoorList\":[{\"doorIndexCode\":\"4a50523a21644823a1b440ea95ce1a7b\",\"doorState\":0}],\"noAuthDoorIndexCodeList\":[]}}\n";
    }

    private String testDoorEvent() {
        return "{\"code\":\"0\",\"msg\":\"success\",\"data\":{\"pageSize\":3,\"list\":[{\"eventId\":\"625f749daf546ce926074c9ea4587690\",\"eventName\":\"acs.acs.eventType.failNotSuitTimeInterval\",\"eventTime\":\"2024-08-05T14:41:54+08:00\",\"personId\":\"281ea04bb2b94d3caa41d5b70298a83e\",\"cardNo\":\"0106893691\",\"personName\":\"管理3\",\"orgIndexCode\":\"feab0250-786c-4f6e-84b0-5ae9a3456b6f\",\"orgName\":\"中原证券北环中心机房/管理\",\"doorName\":\"信创区西门\",\"doorIndexCode\":\"f1278312a9f94a4683ab3830821032d6\",\"doorRegionIndexCode\":\"5443f6b074f640cc9643f3fdb5d4f0c8\",\"picUri\":null,\"svrIndexCode\":null,\"eventType\":197384,\"inAndOutType\":1,\"readerDevIndexCode\":\"9095c4c5d3574d45bc7768380bc2ed17\",\"readerDevName\":\"读卡器_1\",\"devIndexCode\":\"a202bd83e27b422f94951c214980cfe4\",\"devName\":\"新机房门禁控制器1\",\"identityCardUri\":null,\"receiveTime\":\"2024-08-05T14:45:15.388+08:00\",\"jobNo\":null,\"studentId\":null,\"certNo\":\"0106893691\",\"temp\":null},{\"eventId\":\"edf5ab9d76de0280060a387937b3723b\",\"eventName\":\"acs.acs.eventType.failNotSuitTimeInterval\",\"eventTime\":\"2024-08-05T14:41:50+08:00\",\"personId\":\"281ea04bb2b94d3caa41d5b70298a83e\",\"cardNo\":\"0106893691\",\"personName\":\"管理3\",\"orgIndexCode\":\"feab0250-786c-4f6e-84b0-5ae9a3456b6f\",\"orgName\":\"中原证券北环中心机房/管理\",\"doorName\":\"信创区西门\",\"doorIndexCode\":\"f1278312a9f94a4683ab3830821032d6\",\"doorRegionIndexCode\":\"5443f6b074f640cc9643f3fdb5d4f0c8\",\"picUri\":null,\"svrIndexCode\":null,\"eventType\":197384,\"inAndOutType\":1,\"readerDevIndexCode\":\"9095c4c5d3574d45bc7768380bc2ed17\",\"readerDevName\":\"读卡器_1\",\"devIndexCode\":\"a202bd83e27b422f94951c214980cfe4\",\"devName\":\"新机房门禁控制器1\",\"identityCardUri\":null,\"receiveTime\":\"2024-08-05T14:45:15.388+08:00\",\"jobNo\":null,\"studentId\":null,\"certNo\":\"0106893691\",\"temp\":null},{\"eventId\":\"ed330554f0fe3bf9a7b3083832c6dba9\",\"eventName\":\"acs.acs.eventType.failNotSuitTimeInterval\",\"eventTime\":\"2024-08-05T14:40:26+08:00\",\"personId\":\"281ea04bb2b94d3caa41d5b70298a83e\",\"cardNo\":\"0106893691\",\"personName\":\"管理3\",\"orgIndexCode\":\"feab0250-786c-4f6e-84b0-5ae9a3456b6f\",\"orgName\":\"中原证券北环中心机房/管理\",\"doorName\":\"信创区西门\",\"doorIndexCode\":\"f1278312a9f94a4683ab3830821032d6\",\"doorRegionIndexCode\":\"5443f6b074f640cc9643f3fdb5d4f0c8\",\"picUri\":null,\"svrIndexCode\":null,\"eventType\":197384,\"inAndOutType\":1,\"readerDevIndexCode\":\"9095c4c5d3574d45bc7768380bc2ed17\",\"readerDevName\":\"读卡器_1\",\"devIndexCode\":\"a202bd83e27b422f94951c214980cfe4\",\"devName\":\"新机房门禁控制器1\",\"identityCardUri\":null,\"receiveTime\":\"2024-08-05T14:45:15.388+08:00\",\"jobNo\":null,\"studentId\":null,\"certNo\":\"0106893691\",\"temp\":null}],\"total\":3,\"totalPage\":1,\"pageNo\":1}}\n";
    }
}
